package app.nexd.com.indoor.presenter;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.route.RoutePlanSearch;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import app.nexd.com.indoor.R;
import app.nexd.com.indoor.activity.NexdMapViewActivity;
import app.nexd.com.indoor.activity.inter.IBDMapViewActivity;
import app.nexd.com.indoor.application.MyApplication;
import app.nexd.com.indoor.http.InputStreamVolleyRequest;
import app.nexd.com.indoor.mode.FloorModel;
import app.nexd.com.indoor.mode.MallModel;
import app.nexd.com.indoor.presenter.inter.IBDMapViewPresenter;
import app.nexd.com.indoor.util.FileUtil;
import app.nexd.com.indoor.util.UrlUtil;

/**
 * 百度地图页面业务处理类
 * Created by lawrence on 2015/11/10.
 */
public class IBDMapViewPresenterImpl implements IBDMapViewPresenter {
    private static final String TAG = IBDMapViewPresenterImpl.class.getSimpleName();
    //  配置定位参数
    private LocationClient mLocationClient = null;
    //  百度定位监听
    private BDLocationListener myListener = null;
    // 是否是第一次定位
    private boolean isFirstLocation = true;
    // 百度地图视图接口
    private IBDMapViewActivity ibdMapViewActivity;
    // 百度地图对象
    private MapView mMapView;
    // 当前activity的上下文对象
    private Context context;
    // 百度地图的路径规划对象
    private RoutePlanSearch routePlanSearch;
    // 上次点的集合的尾巴
    private LatLng lastLastLatLng;

    public IBDMapViewPresenterImpl(Context context, IBDMapViewActivity ibdMapViewActivity, MapView mMapView) {
        this.ibdMapViewActivity = ibdMapViewActivity;
        this.mMapView = mMapView;
        this.context = context;
        this.mLocationClient = new LocationClient(context);     //声明LocationClient类
        this.routePlanSearch = RoutePlanSearch.newInstance();
        myListener = new MyLocationListener();
        mLocationClient.registerLocationListener(myListener);    //注册监听函数
    }

    @Override
    public void initMap() {
        initLocation();
    }

    @Override
    public void startLocation() {
        mLocationClient.start();
    }

    @Override
    public void stopLocation() {
        mLocationClient.stop();
    }

    @Override
    public void requestAllMalls(String cityCode) {
        StringBuffer url = new StringBuffer();
        url.append(UrlUtil.BASE_REQUEST_URL);
        url.append("/v1.0/getBuildingInfo.do?cityCode=" + cityCode);
        url.append("&appKey=f4b5aeaa1776f7af714e0663fa2e50b2");
        Log.d("requestAllMalls", url.toString());
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url.toString(), new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.i(TAG, response);
                if (!TextUtils.isEmpty(response)) {
                    try {
                        JSONObject resultJson = new JSONObject(response);
                        if (resultJson.getBoolean("isSuccess")) {
                            ArrayList<MallModel> mallModels = new ArrayList<>();
                            JSONArray mallArrays = resultJson.getJSONArray("malls");
                            for (int i = 0; i < mallArrays.length(); i++) {
                                JSONObject mallObj = mallArrays.getJSONObject(i);
                                MallModel mallModel = new MallModel();
                                mallModel.setId(mallObj.getString("mallId"));
                                mallModel.setName(mallObj.getString("mallCName"));
                                mallModel.setLat(Double.parseDouble(mallObj.getString("baiduLat")));
                                mallModel.setLng(Double.parseDouble(mallObj.getString("baiduLng")));
                                mallModel.setMd5(mallObj.getString("md5"));
                                mallModel.setUrl(mallObj.getString("url"));
                                mallModels.add(mallModel);
                            }

                            BitmapDescriptor bitmap = BitmapDescriptorFactory
                                    .fromResource(R.drawable.icon_shopping);
                            for (MallModel mallModel : mallModels) {

                                LatLng point = new LatLng(mallModel.getLat(), mallModel.getLng());

                                Bundle bundle = new Bundle();
                                bundle.putParcelable("MallModel", mallModel);

                                OverlayOptions option = new MarkerOptions()
                                        .position(point)
                                        .title(mallModel.getName())
                                        .extraInfo(bundle)
                                        .icon(bitmap);

                                ibdMapViewActivity.addOverlay(option);
                            }
                        } else {
                            ibdMapViewActivity.showToast("暂不支持该城市，敬请期待！");
                        }
                    } catch (JSONException e) {
                        MyApplication.getInstance().reportException(e);
                    }
                } else {
                    ibdMapViewActivity.showToast("商场数据更新失败");
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                ibdMapViewActivity.showToast("请检查你的网络连接");
            }
        });
        MyApplication.getInstance().addToRequestQueue(stringRequest);
    }

    // 获取某商场的楼层信息
    private void requestFloors(final Context context, final MallModel mallModel) {
        StringBuffer url = new StringBuffer();
        url.append(UrlUtil.BASE_REQUEST_URL);
        url.append("/v1.0/getFloorsInfo.do?buildingCode=");
        url.append(mallModel.getId());
        url.append("&appKey=f4b5aeaa1776f7af714e0663fa2e50b2");
        Log.d("requestFloors", url.toString());
        StringRequest floorsRequest = new StringRequest(Request.Method.POST, url.toString(), new Response.Listener<String>() {
            /**
             * Called when a response is received.
             *
             * @param response
             */
            @Override
            public void onResponse(String response) {
                if (!TextUtils.isEmpty(response)) {
                    Log.d("requestFloors", response);
                    try {
                        JSONObject floorResultJson = new JSONObject(response);
                        if (floorResultJson.getBoolean("isSuccess")) {
                            JSONArray floorArrays = floorResultJson.getJSONArray("floors");
                            ArrayList<FloorModel> floorModelArrayList = new ArrayList<>();
                            for (int i = 0; i < floorArrays.length(); i++) {
                                JSONObject floorModelObj = floorArrays.getJSONObject(i);
                                FloorModel floorModel = new FloorModel(floorModelObj.getString("floorId"),
                                        floorModelObj.getString("floorName"), Integer.parseInt(floorModelObj.getString("floorLayer")));
                                floorModelArrayList.add(floorModel);
                            }

                            Collections.sort(floorModelArrayList, new Comparator<FloorModel>() {
                                @Override
                                public int compare(FloorModel lhs, FloorModel rhs) {
                                    return lhs.getFloorLayer() - rhs.getFloorLayer();
                                }
                            });

                            // 准备就绪，准备进入nexdmap地图页面
                            intoNexdMap(context, floorModelArrayList, mallModel);
                        } else {
                            ibdMapViewActivity.showToast("数据更新失败");
                        }
                    } catch (JSONException e) {
                        MyApplication.getInstance().reportException(e);
                    }
                }
            }
        }, new Response.ErrorListener() {
            /**
             * Callback method that an error has been occurred with the
             * provided error code and optional user-readable message.
             *
             * @param error
             */
            @Override
            public void onErrorResponse(VolleyError error) {
                MyApplication.getInstance().reportException(error);
            }
        });
        MyApplication.getInstance().addToRequestQueue(floorsRequest);
        floorsRequest.setRetryPolicy(new DefaultRetryPolicy(6000, 3, 0));
    }

    @Override
    public void enterNexdMap(Context context, MallModel mallModel) {
        if (isFileExist(mallModel)) {
            Log.d("checkUpdate", "准备检查更新");
            checkUpdate(context, mallModel);
        } else {
            Log.d("downLoadFile", "准备下载文件" + mallModel.getUrl());
            downloadFile(context, mallModel.getUrl(), mallModel);
        }
    }

    // 检查文件是否存在
    private boolean isFileExist(MallModel mallModel) {
        String filePath = UrlUtil.BASE_FILE_PATH + mallModel.getId();
        return FileUtil.checkExist(filePath);
    }

    // 检查本地文件更新
    private void checkUpdate(final Context context, final MallModel mallModel) {
        // 失败，获取下载地址，进行下载， 成功，直接load地图信息，执行页面跳转
        StringBuffer url = new StringBuffer();
        url.append(UrlUtil.BASE_REQUEST_URL);
        url.append("/v1.0/checkProp.do?buildingCode=");
        url.append(mallModel.getId());
        url.append("&md5=");
        url.append(mallModel.getMd5());
        url.append("&appKey=f4b5aeaa1776f7af714e0663fa2e50b2");
        android.util.Log.d("checkUpdate", url.toString());
        StringRequest checkUpdateRequest = new StringRequest(Request.Method.POST, url.toString(), new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (!TextUtils.isEmpty(response)) {
                    try {
                        JSONObject resultJson = new JSONObject(response);
                        cn.nexd.map.location.utils.Log.d("checkUpdate", resultJson);
                        if (resultJson.getBoolean("isSuccess")) {
                            if (resultJson.getString("msgCode").equals(UrlUtil.WEB_API_APP_NEED_UPDATE_PROP)) {
                                Log.d("checkUpdate", "需要更新");
                                mallModel.setMd5(resultJson.getString("md5"));
                                downloadFile(context, resultJson.getString("url"), mallModel);
                            } else {
                                Log.d("checkUpdate", "不需要更新!");
                                requestFloors(context, mallModel);
                            }
                        }
                    } catch (JSONException e) {
                        MyApplication.getInstance().reportException(e);
                    }
                }
            }


        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                MyApplication.getInstance().reportException(error);
            }
        });
        MyApplication.getInstance().addToRequestQueue(checkUpdateRequest);
        checkUpdateRequest.setRetryPolicy(new DefaultRetryPolicy(6000, 3, 0));
    }

    // 跳转到NexdMap地图
    private void intoNexdMap(Context context, ArrayList floorModelArrayList, MallModel mallModel) {
        Intent intent = new Intent(context, NexdMapViewActivity.class);
        intent.putExtra("FloorModels", floorModelArrayList);
        intent.putExtra("MallModel", mallModel);
        context.startActivity(intent);
    }

    // 下载对应商场的配置和地图信息
    private void downloadFile(final Context context, String url, final MallModel mallModel) {
        Log.d("downloadFile", url);
        InputStreamVolleyRequest downloadRequest = new InputStreamVolleyRequest(Request.Method.POST, url, new Response.Listener<byte[]>() {
            /**
             * Called when a response is received.
             *
             * @param response
             */
            @Override
            public void onResponse(byte[] response) {
                if (response == null || response.length == 0) {
                    ibdMapViewActivity.showToast("数据更新失败");
                    return;
                } else {
                    try {
                        StringBuffer savePath = new StringBuffer();
                        savePath.append(UrlUtil.DOWNLOAD_FILE_PATH);
                        savePath.append(File.separator);
                        savePath.append(mallModel.getId());
                        savePath.append(".zip");
                        File zipFile = FileUtil.writeFile(savePath.toString(), response);// 存储下载文件
//                        String filePath = UrlUtil.DOWNLOAD_FILE_PATH + File.separator; // 拼接
                        FileUtil.unCompressZipFile(savePath.toString(), zipFile.getParent() + File.separator); // 解压压缩包，存放在下载目录
                        FileUtil.deleteFileOrDir(savePath.toString()); // 删除压缩包文件
                        // filePath ==> map_svg/download/10101001
                        savePath.setLength(0);
                        savePath.append(UrlUtil.DOWNLOAD_FILE_PATH);
                        savePath.append(File.separator);
                        savePath.append(mallModel.getId());
                        FileUtil.shearFile(savePath.toString(), UrlUtil.BASE_FILE_PATH); // 将解压出来的文件，剪切到父级目录中
                        ibdMapViewActivity.showToast("下载完成!");
                        requestFloors(context, mallModel);
                        savePath = null;

                    } catch (IOException e) {
                        ibdMapViewActivity.showToast("数据更新失败");
                        MyApplication.getInstance().reportException(e);
                    }
                    Log.i("downloadFile", response.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                ibdMapViewActivity.showToast("数据更新失败");
            }
        }, null);
        MyApplication.getInstance().addToRequestQueue(downloadRequest);
        downloadRequest.setRetryPolicy(new DefaultRetryPolicy(6000, 3, 0));
    }

    // 初始化定位参数
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span = 3000;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(false);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(false);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认false，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        option.setLocationNotify(true);
        mLocationClient.setLocOption(option);
    }

    // 百度地图定位监听
    private class MyLocationListener implements BDLocationListener {
        MapStatusUpdate u = null;

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null || mMapView == null) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                            // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(100)
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            if (isFirstLocation) {
                isFirstLocation = false;
                LatLng ll = new LatLng(location.getLatitude(),
                        location.getLongitude());
                u = MapStatusUpdateFactory.newLatLng(ll);
                ibdMapViewActivity.animateMapStatus(u);
            }
            stopLocation();
            ibdMapViewActivity.setLocationData(locData);
        }
    }
}
